/**
 * 封装全局接口请求axios函数
 */

import axios from 'axios'
import JSONBIGINT from 'json-bigint'
// 导入store => 和组件中的this.$store
import store from '../store'
// 导入路由实例=> router => 和组件中的this.$router
import router from '../router'
// console.log(store)

const MyAxios = axios.create({
  baseURL: 'http://ttapi.research.itcast.cn/app/v1_0/',
  // 'http://toutiao-app.itheima.net/v1_0'
  transformResponse: [function (data) {
    // console.log('1', data)
    // Do whatever you want to transform the data
    // data =>后台返回的JSON字符串
    try {
      // 处理JSON.parse/stringify精度丢失
      // test:console.log(JSONBIGINT.parse('{"a":9223372036854775807}').a.toString(), JSON.parse('{"a":9223372036854775807}'))
      return JSONBIGINT.parse(data)
    } catch (e) {
      return data
    }
  }
  ]

})

// Add a request interceptor
MyAxios.interceptors.request.use(function (config) {
  // Do something before request is sent
  // 请求之前，统一向header中加入token=> 从vuex获取token
  // ?.user 处理null
  // console.log(config)
  // 处理接口版本问题
  if (config.url === 'articles') {
    config.baseURL = config.baseURL.replace('v1_0', 'v1_1')
  }
  if (store.state.user.token && config.url !== 'authorizations') {
    config.headers.Authorization = `Bearer ${store.state.user.token}`
  }
  return config
}, function (error) {
  // Do something with request error
  return Promise.reject(error)
})

// Add a response interceptor
MyAxios.interceptors.response.use(function (response) {
  // Any status code that lie within the range of 2xx cause this function to trigger
  // Do something with response data
  // 处理和简化返回的数据=》到这里组件还没有获取到数据！！！
  // 只留下需要的数据=》返回给页面使用
  return {
    status: response.status,
    data: response.data.data
  }
}, async function (error) {
  // Any status codes that falls outside the range of 2xx cause this function to trigger
  // Do something with response error
  console.log('捕获401:', error.response)
  // js路由跳转？=>导入路由实例=> router.push({path:'', query:{}})
  /**
   * 准备跳转的路径和参数
   * 1. 登录配置
   * 2. 传递给登录的参数query=》目的：告诉登录页上次访问的页面是谁=》登录成功后，跳转回上次访问页面
   */
  const loginConfig = { path: '/login', query: { backUrl: router.currentRoute.path } }
  try {
    if (error?.response?.status === 401) {
      // 从vuex获取token
      const { user } = store.state
      // 1. 没有登录过=》根据有没有token
      if (!user.token || !user.refresh_token) {
        router.replace(loginConfig)
        return Promise.reject(error)
      }
      // 2. 登录过
      /**
       * 1. token失效，refresh_token没有失效=》获取新token
       * 2. 两个token都失效
       */
      // 根据refresh_token调用刷新token接口
      const { status, data } = await MyAxios.put('authorizations', null, {
        headers: {
          Authorization: `Bearer ${user.refresh_token}`
        }
      })
      if (status === 201) {
        console.log(status, data)
        // 更新vuex中的老token
        store.commit('setToken', {
          // 后台获取的新token
          token: data.token,
          refresh_token: user.refresh_token
        })
        // 继续上次401的请求=>error.config上次401请求的配置{url:'',method:''}
        return MyAxios(error.config)
      }
    }
  } catch (error) {
    console.log('两个token都失效=>跳回登录:', error)
    // 两个token都失效=>跳回登录
    router.replace(loginConfig)
    return Promise.reject(error)
  }
  return Promise.reject(error)
})

// 封装vue插件=> Vue.use调用插件方法，传入Vue
const MyAxiosPlug = function (Vue) {
  // 原型上定义全局方法
  Vue.prototype.request = MyAxios
}

export function abc () {
  return 123
}

export const cde = 1

// 导出插件
export { MyAxiosPlug }
// 导出axios
export default MyAxios
